package com.clippick;

import java.io.File;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.json.JSONException;
import org.json.JSONObject;

import android.annotation.TargetApi;
import android.app.FragmentTransaction;
import android.app.NotificationManager;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.StrictMode;
import android.provider.MediaStore;
import android.text.ClipboardManager;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.TextView;
import co.kr.clippick.R;

import com.clippick.api.GetApi;
import com.clippick.clipboard.PollingService;
import com.clippick.clipboard.ShorcutNotificationService;
import com.clippick.common.GlobalValue;
import com.clippick.common.Toasts;
import com.clippick.common.Utils;
import com.clippick.database.ClipData;
import com.clippick.database.FeedOrderDBAdapter;
import com.clippick.database.HistoryDBAdapter;
import com.clippick.dbbusiness.DBBusiness;
import com.clippick.history.FullScreenImageViewer;
import com.slidingmenu.lib.SlidingMenu;
import com.slidingmenu.lib.SlidingMenu.ViewStateChnagedListener;
import com.slidingmenu.lib.app.SlidingFragmentActivity;

public class NewMainActivity extends SlidingFragmentActivity implements
		OnItemClickListener, ViewStateChnagedListener {

	private Context mContext;
	private Button sliderButton, sendMemoButton;
	private EditText memoEditText;
	private ProgressBar indicator;
	private LinearLayout sliderButtonLayer;
	private ListView list;
	private TextView title;

	private ClipAdapter adapter;

	private List<Map> items;

	private ConnectivityManager manager;

	// system cliboard
	@SuppressWarnings("deprecation")
	private ClipboardManager systemClipboard;

	// ping-pong test
	private Thread pingThread;
	private boolean isPingAlive = false;

	public static boolean IS_STAR_VIEW = false;

	@TargetApi(11)
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		if (android.os.Build.VERSION.SDK_INT < 11) {
			requestWindowFeature(Window.FEATURE_NO_TITLE);
		} else {
			getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
		}

		mContext = this;

		setContentView(R.layout.new_main);
		setBehindContentView(R.layout.behind);

		IntentFilter filterUpdatePolling = new IntentFilter();
		filterUpdatePolling.addAction("com.new.clippick.UpdatePolling");
		registerReceiver(updatePolling, filterUpdatePolling);

		IntentFilter filterShowIndicator = new IntentFilter();
		filterShowIndicator.addAction("com.new.clippick.showIndicator");
		registerReceiver(showIndicator, filterShowIndicator);

		// set behind View
		if (Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB) {
			FragmentTransaction t = this.getFragmentManager().beginTransaction();
			t.add(R.id.frame, new BehindFragment());
			t.commit();
		} else {
			android.support.v4.app.FragmentTransaction t = 
					this.getSupportFragmentManager().beginTransaction();
			t.add(R.id.frame, new BehindFragmentV4());
			t.commit();
		}
		

		// set the SlidingMenu
		this.setSlidingActionBarEnabled(true);
		getSlidingMenu().setBehindOffsetRes(R.dimen.actionbar_home_width);
		getSlidingMenu().setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);
		getSlidingMenu().setShadowWidthRes(R.dimen.shadow_width);
		getSlidingMenu().setShadowDrawable(R.drawable.shadow);
		getSlidingMenu().setBehindScrollScale(0.25f);
		getSlidingMenu().setOnViewStateChangedListener(this);

		// set sliding toggle action
		sliderButtonLayer = (LinearLayout) findViewById(R.id.back_button_layer);
		sliderButton = (Button) findViewById(R.id.back);
		this.setToggleButtonAction(sliderButtonLayer);
		this.setToggleButtonAction(sliderButton);

		title = (TextView) findViewById(R.id.title);

		// set list
		adapter = new ClipAdapter(mContext);
		list = (ListView) findViewById(R.id.listview);
		list.setOnItemClickListener(this);
		list.setAdapter(adapter);

		indicator = (ProgressBar) findViewById(R.id.indicator);
		// hide default
		indicator.setVisibility(View.INVISIBLE);

		/**
		if (Utils.isAndroidLowerThanICS()) {
			// remove title
			requestWindowFeature(Window.FEATURE_NO_TITLE);
		} else {
			StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
					.permitAll().build();
			StrictMode.setThreadPolicy(policy);
		}
		*/

		manager = (ConnectivityManager) mContext
				.getSystemService(Context.CONNECTIVITY_SERVICE);

		memoEditText = (EditText) findViewById(R.id.reply_text);

		sendMemoButton = (Button) findViewById(R.id.send);
		sendMemoButton.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				String memoText = memoEditText.getText().toString();
				if (Utils.checkNetwokState(manager)) {
					if (!memoText.equals("")) {
						insertMemoClip(memoText);
					}
				} else {
					Toasts.showToast(mContext, getString(R.string.network_fail));
				}

				hideKeyboard(memoEditText);
			}
		});

		// prevent unauthorized user to show MainActivity
		if (GlobalValue.USER_ID.equals("")) {
			Intent intent = new Intent(mContext, NewLoginActivity.class);
			startActivity(intent);
			finish();
		}

		// system clipboard
		systemClipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);

		// set empty clipboard
		systemClipboard.setText("");

		// open local database manager
		String dbTableName =  GlobalValue.getUserEmail(mContext).replace("@", "").replace(".", "").replace("-", "");
		GlobalValue.setDbTableName(mContext, HistoryDBAdapter.DATABASE_TABLE_PRE + dbTableName);
		GlobalValue.setImageOrderDbTableName(mContext, FeedOrderDBAdapter.DATABASE_TABLE_PRE + dbTableName);
		
		DBBusiness.startDBs(this);
		
		// start screen on/off monitor
		GlobalValue.saveBackgroundPref(this, GlobalValue.ACT_ON_SERVICE_ON);
		GlobalValue.saveFirstSyncComplete(mContext, true);

		// start background service
//		if (GlobalValue.isAutoSync(mContext)) {
			startClipService();
//		}

		startForegroundNotification();

		this.updateClipList(false);

		moveListViewPositionToBottom(list);
	}

	private void moveListViewPositionToBottom(ListView _list) {
		_list.postDelayed(new Runnable() {
			@Override
			public void run() {
				if (!items.isEmpty()) {
					list.setSelection(items.size() - 1);
				}
			}
		}, 100L);
	}

	public void showImageFullScreen(Map item) {
		String path = item.get(FeedOrderDBAdapter.KEY_DB_TEXT_PATH).toString();
		Intent intent = new Intent(mContext, FullScreenImageViewer.class);
		intent.putExtra("path", path);
		startActivity(intent);
		overridePendingTransition(android.R.anim.fade_in,
				android.R.anim.fade_out);
	}

	private void hideKeyboard(EditText editText) {
		InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
		imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
	}

	BroadcastReceiver updatePolling = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {

			// get clip data as Map
			updateClipList(IS_STAR_VIEW);

			// dismiss indicator
			handleIndicator(false);

			GlobalValue.IS_UPDATING = false;
		}
	};

	BroadcastReceiver showIndicator = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
			if (intent.getExtras() != null) {
				// show indicator
				handleIndicator(intent.getExtras().getBoolean("show"));
			}
		}
	};

	public void handleIndicator(boolean value) {
		if (value) {
			// show
			indicator.setVisibility(View.VISIBLE);
			GlobalValue.IS_UPDATING = true;
		} else {
			// hide
			indicator.setVisibility(View.INVISIBLE);
			GlobalValue.IS_UPDATING = false;
		}
	}

	private void updateClipList(boolean isStarClip) {
		if (!isStarClip) {
			items = DBBusiness.fetchClipFromDb();
		} else {
			items = DBBusiness.fetchStarClipFromDb();
		}
		
		for (int i = 0; i < items.size(); i++) {
			Map item = new HashMap();
			item.putAll(items.get(i));
			item.put("preview", true);

			items.set(i, item);
		}

		if (!items.isEmpty())
			Collections.reverse(items);

		adapter.addClipData(items);
		adapter.notifyDataSetChanged();

		moveListViewPositionToBottom(list);
	}

	/** start monitor polling system clipboard on background */
	private void startClipService() {
		Intent intent = new Intent(mContext, PollingService.class);
		startService(intent);
	}

	private void startForegroundNotification() {
		Intent intent = new Intent(mContext, ShorcutNotificationService.class);
		if (GlobalValue.isShowNotification(mContext)) {
			startService(intent);
		} else {
			stopService(intent);
		}
	}

	public void onPause() {
		super.onPause();
		isPingAlive = false;
		pingThread.interrupt();

		int nBackStatus = GlobalValue.getBackgroundOn(this);
		switch (nBackStatus) {
		case GlobalValue.ACT_ON_SERVICE_OFF:
			GlobalValue.saveBackgroundPref(this,
					GlobalValue.ACT_OFF_SERVICE_OFF);
			break;
		case GlobalValue.ACT_ON_SERVICE_ON:
			GlobalValue
					.saveBackgroundPref(this, GlobalValue.ACT_OFF_SERVICE_ON);
			break;
		default:
			break;
		}
	}

	public void onDestroy() {
		super.onDestroy();

		unregisterReceiver(updatePolling);
		unregisterReceiver(showIndicator);

		// kill db
		DBBusiness.closeDbs();

		isPingAlive = false;

		if (pingThread != null)
			pingThread.interrupt();
	}

	public void onResume() {
		super.onResume();
		Log.i("activity", "NewMainActivity.onResume()");
		int nBackStatus = GlobalValue.getBackgroundOn(this);
		switch (nBackStatus) {
		case GlobalValue.ACT_OFF_SERVICE_OFF:
			GlobalValue
					.saveBackgroundPref(this, GlobalValue.ACT_ON_SERVICE_OFF);
			break;
		case GlobalValue.ACT_OFF_SERVICE_ON:
			GlobalValue.saveBackgroundPref(this, GlobalValue.ACT_ON_SERVICE_ON);
			break;
		default:
			break;
		}

		// check image shared from SharedMenu
		checkSharedMenu();

		// remove notification: image sync
		NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
		notificationManager.cancelAll();

		// prevent unauthorized user to show MainActivity
		if (GlobalValue.USER_ID.equals("")) {
			Intent intent = new Intent(mContext, LoginActivity.class);
			startActivity(intent);
			finish();
		}

		this.isPingAlive = true;
		pingThread = new Thread(new Runnable() {
			@Override
			public void run() {
				while (isPingAlive) {
					GetApi api = new GetApi();
					api.sendPing();
					try {
						Thread.sleep(7500);
					} catch (InterruptedException ignored) {

					}
				}
			}
		});

		pingThread.start();

		// send broadcast to do connect longpolling
		if (Utils.checkNetwokState(manager)) {
			if (PollingService.CONNECTED_COUNT == 0) {
				Intent intent = new Intent();
				intent.setAction("com.clippick.LongPoll");
				sendBroadcast(intent);
			}
		}
	}

	private void checkSharedMenu() {
		if (Intent.ACTION_SEND.equals(getIntent().getAction())) {
			if (GlobalValue.USER_ID.equals("")) {
				Toasts.showToast(mContext, "please login");
			} else {
				Intent intent = new Intent();
				intent.setAction("com.clippick.TransferImage");
				intent.putExtras(getIntent());
				sendBroadcast(intent);
			}

			finish();
		}
	}

	public void showAbove() {
		super.showAbove();
		this.updateClipList(IS_STAR_VIEW);

		// set view layout
		LayoutParams params;
		params = new LayoutParams((int) Utils.convertDpToPixel(85, mContext),
				(int) Utils.convertDpToPixel(20, mContext));
		params.addRule(RelativeLayout.CENTER_IN_PARENT);

		// get title view background image
		Drawable backgroundTitleDrawable = getResources().getDrawable(
				R.drawable.main_title);

		if (IS_STAR_VIEW) {
			params = new LayoutParams((int) Utils.convertDpToPixel(140,
					mContext), (int) Utils.convertDpToPixel(21, mContext));
			params.addRule(RelativeLayout.CENTER_IN_PARENT);

			backgroundTitleDrawable = getResources().getDrawable(
					R.drawable.main_title_star);
		}

		title.setLayoutParams(params);
		title.setBackgroundDrawable(backgroundTitleDrawable);
	}

	public void showBehind() {
		// getSlidingMenu().setOnPageChangeListener()
		super.showBehind();
	}

	private void setToggleButtonAction(View v) {
		v.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				toggle();
			}
		});
	}

	public void setActiveOrInactiveStar(Map<?, ?> item) {
		String starValue = item.get(HistoryDBAdapter.KEY_DB_KEEPBOX).toString();
		String clipIndex = item.get(HistoryDBAdapter.KEY_DB_NO).toString();
		if (starValue.equals("1")) {
			starValue = "0";
		} else {
			starValue = "1";
		}
		new HttpTask().execute(clipIndex, starValue, "star");
	}

	public void deleteClip(String clipIndex) {
		new HttpTask().execute(clipIndex, "", "delete");
	}

	public void shareClip(Map<?, ?> clip) {
		// check text or image
		String imageUri = clip.get(HistoryDBAdapter.KEY_DB_IMG).toString();
		String text = clip.get(HistoryDBAdapter.KEY_DB_CONTENTS).toString();

		if (imageUri.equals("")) {
			// share text
			if (!text.startsWith("_", 0) && !(text.length() == 14)) {
				Intent sendIntent = new Intent();
				sendIntent.setAction(Intent.ACTION_SEND);
				sendIntent.putExtra(Intent.EXTRA_TEXT, text);
				sendIntent.setType("text/plain");
				startActivity(Intent.createChooser(sendIntent, "Share to"));
			}
		} else {
			// share image
			String path = clip.get(FeedOrderDBAdapter.KEY_DB_TEXT_PATH)
					.toString();
			File imageFile = new File(path);
			Uri uriToImage = Uri.fromFile(imageFile);
			Intent shareIntent = new Intent();
			shareIntent.setAction(Intent.ACTION_SEND);
			shareIntent.putExtra(Intent.EXTRA_STREAM, uriToImage);
			shareIntent.setType("image/*");
			startActivity(Intent.createChooser(shareIntent, "Share to"));
		}
	}

	private void insertMemoClip(String content) {
		new HttpTask().execute(content, "", "memo");
	}

	public void copyContent(Map clickedClip) {
		String imageUri = clickedClip.get(HistoryDBAdapter.KEY_DB_IMG)
				.toString();
		String text = clickedClip.get(HistoryDBAdapter.KEY_DB_CONTENTS)
				.toString();

		if (imageUri.equals("")) {
			// copy content
			if (!text.startsWith("_", 0) && !(text.length() == 14)
					&& !text.equals("[img0]")) {
				GlobalValue.AppClip = text;
				GlobalValue.PrevClip = text;
				systemClipboard.setText(text);
				Toasts.showToast(mContext, "clipped");
			}
		} else {
			saveImageGallery(clickedClip);
			Toasts.showToast(mContext, "saved image");
		}
	}

	@SuppressWarnings("unchecked")
	public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
		hideKeyboard(memoEditText);

		Map clickedClip = new HashMap();
		clickedClip.putAll(items.get(position));

		for (int i = 0; i < items.size(); i++) {
			Map m = new HashMap();
			m.putAll((Map) items.get(i));
			m.put("preview", true);
			items.set(i, m);
		}

		boolean isPreview = (Boolean) clickedClip.get("preview");
		if (isPreview) {
			clickedClip.put("preview", false);
			// copyContent(clickedClip);
		} else {
			clickedClip.put("preview", true);
		}

		items.set(position, clickedClip);

		adapter.addClipData(items);

		adapter.notifyDataSetChanged();
	}

	public void saveImageGallery(Map item) {
		String filePath = item.get(FeedOrderDBAdapter.KEY_DB_TEXT_PATH)
				.toString();
		String imageUrl = item.get(FeedOrderDBAdapter.KEY_DB_IMAGE_URL)
				.toString();

		File file = new File(filePath);
		String fileName = filePath.substring(filePath.lastIndexOf("/") + 1,
				filePath.length());

		if (file.isFile() == false) {
			Utils.downloadFromUrl(imageUrl, filePath);
		}

		if (isImageInGallery(filePath) == false) {
			try {
				if (android.os.Build.PRODUCT.toUpperCase().contains("HTC")) {
					Uri uri = Uri.parse("file://" + filePath);

					Intent intent = new Intent(
							Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
					intent.setData(uri);
					sendBroadcast(intent);
				} else {
					insertGallery(filePath, file, fileName);
				}
			} catch (Exception e) {
				Log.e("insertImage", "Error writing file", e);
			}
		}
	}

	private boolean isImageInGallery(String _filePath) {
		String[] proj = { MediaStore.Images.Media._ID,
				MediaStore.Images.Media.DATA,
				MediaStore.Images.Media.DISPLAY_NAME,
				MediaStore.Images.Media.SIZE, MediaStore.Images.Media.TITLE };

		ContentResolver contentResolver = getContentResolver();
		Cursor imageCursor = contentResolver.query(
				MediaStore.Images.Media.EXTERNAL_CONTENT_URI, proj,
				MediaStore.Images.Media.DATA + "='" + _filePath + "'", null,
				null);

		if (imageCursor != null && imageCursor.moveToFirst()) {
			if (imageCursor.getCount() > 0) {

				imageCursor.close();
				return true;
			}
		}
		imageCursor.close();
		return false;
	}

	private void insertGallery(String _filePath, File file, String fileName) {

		ContentValues values = new ContentValues();

		values.clear();
		values.put(MediaStore.Images.Media.TITLE, _filePath);
		values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
		values.put(MediaStore.Images.Media.DATA, file.getAbsolutePath());
		values.put(MediaStore.Images.Media.DISPLAY_NAME, fileName);

		ContentResolver contentResolver = getContentResolver();

		try {
			Uri uri = contentResolver.insert(
					MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);

			if (uri == null) {
				// Exception 객체 Throw 하기
			} else {
				sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
						uri));
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/** HTTP Request from background */
	class HttpTask extends AsyncTask<String, String, String> {
		ProgressDialog mProgress;
		String id = "";
		String result = "";
		Map<String, String> starResult = new HashMap<String, String>();

		protected void onPreExecute() {
			handleIndicator(true);
		}

		@Override
		protected String doInBackground(String... params) {
			GetApi api = new GetApi();
			id = params[2];

			try {
				if (params[2].equals("star")) {
					starResult = api.setStarApi(params[0], params[1]);
				} else if (params[2].equals("delete")) {
					api.deleteClipApi(params[0]);
				} else if (params[2].equals("image")) {
					// api.insertImageClip(params[0], imageFile);
				} else if (params[2].equals("memo")) {
					// api.insertNewClip(params[0], "1");
					api.insertNodeNewClip(params[0], "1");
				} else if (params[2].equals("invite")) {
					result = api.inviteTinyUrlApi();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}

			return null;
		}

		protected void onPostExecute(String unused) {
			handleIndicator(false);
			if (id.equals("star")) {
				JSONObject json = new JSONObject(starResult);

				try {
					int returnCode = Integer.parseInt(json
							.getString("returnCode"));
					switch (returnCode) {
					case 200:

						break;
					default:
						// tabFragment.updateFeed();
						Toasts.showToast(mContext,
								json.getString("returnMessage"));
						break;
					}

				} catch (NumberFormatException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (JSONException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

			// send tiny url to friends
			if (id.equals("invite")) {
				// sendFriendUrl(result);
			}

			if (id.equals("memo")) {
				hideKeyboard(memoEditText);
				memoEditText.setText("");
				moveListViewPositionToBottom(list);
			}
		}
	}

	@Override
	public void onPageScrollStateChanged(int state) {
		if (state == 0)
			hideKeyboard(memoEditText);
	}
}